﻿using System;
using System.IO;
using System.Drawing;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework.Constraints;
using NUnit.Framework;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using SAKS.ViewModels;
using SAKS.Models;
using SAKS.Services;
using SAKS.IServices;

namespace SAKS.UnitTest.ServicesTest
{
    [TestFixture]
    public class MessageServicesTest : TestBase
    {
        private IMessageServices messageServices;
        private string To = "MessageTestUserTo";
        private string From = "MessageTestUserFrom";
        private Guid ProjectId;

        public MessageServicesTest()
        {
            messageServices = new MessageServices();
        }

        protected override void CreateSomeData(ISession session)
        {
            var admin = new User
            {
                UserName = "MessageServicesTestAdmin",
                LoweredUserName = "MessageServicesTestAdmin",
                IsAnonymous = false,
                LastActivityDate = DateTime.Now
            };
            var project = new Project
            {
                Name = "MessageServicesTestProject",
                Users = new List<User>(),
                Administrator = admin
            };
            var to = new User{
                UserName = To,
                LoweredUserName = To.ToLower(),
                IsAnonymous = false,
                LastActivityDate = DateTime.Now,
            };
            var from = new User
            {
                UserName = From,
                LoweredUserName = From.ToLower(),
                IsAnonymous = false,
                LastActivityDate = DateTime.Now,
            };
            session.Save(admin);
            ProjectId = (Guid)session.Save(project);
            session.Save(to);
            session.Save(from);
            for (int i = 1; i <= 10; i++)
            {
                var messageSent = new MessageSent
                {
                    ToName = to.UserName,
                    FromName = from.UserName,
                    Subject = "Messages Test",
                    Content = "Messages Test",
                    Date = DateTime.Now,
                    HasRead = i % 2 == 0,//5个己读，5 个未读
                };
                var messageReceived = new MessageReceived
                {
                    ToName = to.UserName,
                    FromName = from.UserName,
                    Subject = "Messages Test",
                    Content = "Messages Test",
                    Date = DateTime.Now,
                    HasRead = i % 2 == 0,
                };
                session.Save(messageSent);
                session.Save(messageReceived);
            }
        }

        #region Messages Count
        [Test]
        public void GetMessagesUnReadCountTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                var unReadMessageCount = messageServices.GetMessagesUnReadCount(To);
                Assert.AreEqual(5, unReadMessageCount);
            }
        }
        [Test]
        public void GetMessagesReadCountTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                var unReadMessageCount = messageServices.GetMessagesReadCount(To);
                Assert.AreEqual(5, unReadMessageCount);
            }
        }
        [Test]
        public void GetMessagesSentCountTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                var unReadMessageCount = messageServices.GetMessagesSentCount(From);
                Assert.AreEqual(10, unReadMessageCount);
            }
        }
        [Test]
        public void ZeroMessageCountTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                var unReadMessageCount = messageServices.GetMessagesUnReadCount("NonExsit");
                Assert.AreEqual(0, unReadMessageCount);
            }
        }
        #endregion

        #region Messages List
        [Test]
        public void GetMessagesUnReadTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                int? totalRecords;
                messageServices.Session = session;
                var messages = messageServices.GetMessagesUnRead(To,0,20,out totalRecords);
                Assert.AreEqual(5, messages.Count());
            }
        }

        [Test]
        public void GetMessagesSentTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                int? totalRecords;
                messageServices.Session = session;
                var messages = messageServices.GetMessagesSent(From, 0, 20, out totalRecords);
                Assert.IsTrue(typeof(MessageSentBrief) == messages[0].GetType());
                Assert.AreEqual(10, messages.Count());
            }
        }

        [Test]
        public void GetMessagesReadTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                int? totalRecords;
                messageServices.Session = session;
                var messages = messageServices.GetMessagesRead(To, 0, 20, out totalRecords);
                Assert.AreEqual(5, messages.Count());
            }
        }

        #endregion

        #region Delete Message
        [Test]
        public void  DeleteMessageReceivedTest()
        {
            var mr = new MessageReceived
            {
                ToName = "DeleteMessageReceivedTestTo",
                FromName = "DeleteMessageReceivedTestFrom",
                Subject = "DeleteMessageReceivedTest",
                Content = "DeleteMessageReceivedTest",
                Date = DateTime.Now,
                HasRead = false,
            };
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                Guid id = (Guid)session.Save(mr);
                session.Flush();
                session.Evict(mr);
                Assert.NotNull(session.Get<MessageReceived>(id));
                using (var tx = session.BeginTransaction())
                {
                    messageServices.DeleteMessageReceived(id);
                    tx.Commit();
                }
                Assert.IsNull(session.Get<MessageReceived>(id));
            }
        }
        [Test]
        public void DeleteMessageSentTest()
        {
            var mr = new MessageSent
            {
                ToName = "DeleteMessageSentTestTo",
                FromName = "DeleteMessageSentTestFrom",
                Subject = "DeleteMessageSentTest",
                Content = "DeleteMessageSentTest",
                Date = DateTime.Now,
                HasRead = false,

            };
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                Guid id = (Guid)session.Save(mr);
                session.Flush();
                session.Evict(mr);
                Assert.NotNull(session.Get<MessageSent>(id));
                using (var tx = session.BeginTransaction())
                {
                    messageServices.DeleteMessageSent(id);
                    tx.Commit();
                }
                Assert.IsNull(session.Get<MessageSent>(id));
            }
        }
        #endregion

        #region Send Message
        [Test]
        public void SendMessageTest()
        {
            string to = "SendMessageTestTo";
            string from = "SendMessageTestFrom";
            string subjectAndContent = "SendMessageTest";
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                using (var tx = session.BeginTransaction())
                {
                    messageServices.SendMessage(to, from, subjectAndContent,subjectAndContent);
                    tx.Commit();
                }
                var messageSent = session.QueryOver<MessageSent>().Where(m => m.FromName == from && m.Subject == subjectAndContent).SingleOrDefault();
                var messageReceived =  session.QueryOver<MessageReceived>().Where(m => m.ToName == to && m.Subject == subjectAndContent).SingleOrDefault();
                Assert.NotNull(messageSent);
                Assert.NotNull(messageReceived);
            }
        }
        [Test]
        public void SendRemovedFromProjectMessageTest()
        {

            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                using (var tx = session.BeginTransaction())
                {
                    messageServices.SendRemovedFromProjectMessage("SendRemovedFromProjectMessageTest", ProjectId);
                    tx.Commit();
                }
                var messageReceived = session.QueryOver<MessageReceived>().Where(m => m.ToName == "SendRemovedFromProjectMessageTest").SingleOrDefault();
                Assert.NotNull(messageReceived);
            }
        }
        [Test]
        public void SendProjectJoinMessageTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                using (var tx = session.BeginTransaction())
                {
                    messageServices.SendProjectJoinMessage("SendProjectJoinMessageTest", ProjectId,"");
                    tx.Commit();
                }
                var admin = session.Get<Project>(ProjectId).Administrator.UserName;
                var messageReceived = session.QueryOver<MessageReceived>().Where(m => m.ToName == admin).SingleOrDefault();
                Assert.NotNull(messageReceived);
            }
        }
        [Test]
        public void SendJoinRequestApproveMessageTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                using (var tx = session.BeginTransaction())
                {
                    messageServices.SendJoinRequestApproveMessage("SendJoinRequestApproveMessageTest","Test");
                    tx.Commit();
                }
                var messageReceived = session.QueryOver<MessageReceived>().Where(m => m.ToName == "SendJoinRequestApproveMessageTest").SingleOrDefault();
                Assert.NotNull(messageReceived);
            }
        }
        [Test]
        public void SendJoinRequestRejectMessageTest()
        {
            using (var session = sessionFactory.OpenSession())
            {
                messageServices.Session = session;
                using (var tx = session.BeginTransaction())
                {
                    messageServices.SendJoinRequestRejectMessage("SendJoinRequestRejectMessageTest", "Test");
                    tx.Commit();
                }
                var messageReceived = session.QueryOver<MessageReceived>().Where(m => m.ToName == "SendJoinRequestRejectMessageTest").SingleOrDefault();
                Assert.NotNull(messageReceived);
            }
        }
        #endregion

    }
}
